/**
 * Copyright 2011-2011 - Members of the Chaupal Community
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package net.chaupal.API.v1.Bucket;

import net.chaupal.API.Streamable.Streamable;
import net.chaupal.API.v1.Exception.InvalidSizeException;
import net.chaupal.API.v1.Message.MessageNumber;
import net.chaupal.API.v1.Message.MessageType;
import net.chaupal.API.v1.Message.SliceNumber;
import net.chaupal.API.v1.Peer.Hook;
import net.chaupal.API.v1.Peer.PeerID;
import net.chaupal.API.v1.ProtocolVersion1;

/**
 * API definition of the bucket concept as described in the Chaupal protocols.
 */
public interface Bucket extends Streamable<Bucket>, ProtocolVersion1 {

    /**
     * Provides the peer id of the sending peer.
     * 
     * @return the peer id of the sending peer
     */
    PeerID getSourcePeerID();

    /**
     * Sets the peer id of the sending peer.
     * 
     * @param pid the peer id of the sending peer
     */
    void setSourcePeerID(PeerID pid);

    /**
     * Provides the peer id of the receiving peer.
     *
     * @return the peer id of the receiving peer
     */
    PeerID getDestinationPeerID();

    /**
     * Sets the peer id of the receiving peer.
     * 
     * @param pid the peer id of the receiving peer
     */
    void setDestinationPeerID(PeerID pid);

    /**
     * Provides the peer id of the next hop as defined in the Chaupal
     * protocols.
     *
     * @return the peer id of the next hop
     */
    PeerID getNextHop();

    /**
     * Sets the peer id of the next hop as defined in the Chaupal
     * protocols.
     * 
     * @param pid the peer id of the next hop
     */
    void setNextHop(PeerID pid);

    /**
     * Provides the sending peer hook which has sent this bucket.
     *
     * @return the sending peer hook
     */
    Hook getSourceHook();

    /**
     * Sets the hook for the sending peer.
     * 
     * @param h the hook for the sending peer
     */
    void setSourceHook(Hook h);

    /**
     * Provides the receiving peer hook for this bucket.
     *
     * @return the receiving peer hook
     */
    Hook getDestinationHook();

    /**
     * Sets the hook for the receiving peer.
     * 
     * @param h the hook for the sending peer
     */
    void setDestinationHook(Hook h);

    /**
     * Provides the message type of this bucket.
     *
     * @return the message type of this bucket
     */
    MessageType getMessageType();

    /**
     * Sets the message type of this bucket.
     * 
     * @param mt the message type of this bucket
     */
    void setMessageType(MessageType mt);

    /**
     * Provides the message number of this bucket.
     *
     * @return the message number of this bucket
     */
    MessageNumber getMessageNumber();
    
    /**
     * Sets the message number of this bucket.
     * 
     * @param mn the message number of this bucket
     */
    void setMessageNumber(MessageNumber mn);

    /**
     * Provides the slice number of this bucket.
     *
     * @return the slice number of this bucket
     */
    SliceNumber getSliceNumber();

    /**
     * Sets the slice number of this bucket.
     * 
     * @param mn the slice number of this bucket
     */
    void setSliceNumber(SliceNumber mn);

    /**
     * Indicates whether this bucket require confirmation of reception from
     * the target peer.
     *
     * @return {@code true} if this bucket require confirmation of reception,
     * {@code false} otherwise.
     */
    boolean getRequiresConfirmation();

    /**
     * Defines whether this bucket require confirmation of reception from
     * the target peer.
     *
     * @param b {@code true} if this bucket require confirmation of reception,
     * {@code false} otherwise.
     */
    void setRequiresConfirmation(boolean b);

    /**
     * Indicates whether this message is sliced into buckets.
     *
     * @return {@code true} if this message is sliced into buckets,
     * {@code false} otherwise.
     */
    boolean isSliced();

    /**
     * Defines whether this message is sliced into buckets.
     *
     * @param b {@code true} if this bucket is sliced into buckets,
     * {@code false} otherwise.
     */
    void setSliced(boolean b);

    /**
     * Indicates whether this slice is the last sice of a sliced message.
     *
     * @return {@code true} if this slice is the last sice of a sliced message,
     * {@code false} otherwise.
     */
    boolean isLastSlice();

    /**
     * Defines whether this slice is the last sice of a sliced message.
     *
     * @param b {@code true} if this slice is the last sice of
     * a sliced message, {@code false} otherwise.
     */
    void setLastSlice(boolean b);

    /**
     * Indicates whether this bucket contains meta-data.
     *
     * @return {@code true} if this bucket contains meta-data,
     * {@code false} otherwise.
     */
    boolean isMetaData();

    /**
     * Defines whether this bucket contains meta-data.
     *
     * @param b {@code true} if this bucket contains meta-data,
     * {@code false} otherwise.
     */
    void setMetaData(boolean b);

    /**
     * Indicates whether this bucket contains user data.
     *
     * @return {@code true} if this bucket contains user data,
     * {@code false} otherwise.
     */
    boolean isUserData();

    /**
     * Defines whether this bucket contains user data.
     *
     * @param b {@code true} if this bucket contains user data,
     * {@code false} otherwise.
     */
    void setUserData(boolean b);

    /**
     * Indicates whether this message/bucket is embedding another
     * message/bucket.
     *
     * @return {@code true} if this message/bucket is embedding another
     * message/bucket, {@code false} otherwise.
     */
    boolean isEmbedded();

    /**
     * Defines whether this bucket contains an embedded bucket.
     *
     * @param b {@code true} if this bucket contains an embedded bucket,
     * {@code false} otherwise.
     */
    void setEmbedded(boolean b);

    /**
     * Indicates whether this message/bucket is propagated.
     *
     * @return {@code true} if this message/bucket is propagated,
     * {@code false} otherwise.
     */
    boolean isPropagated();

    /**
     * Defines whether this bucket should be propagated.
     *
     * @param b {@code true} if this bucket should be propagated,
     * {@code false} otherwise.
     */
    void setPropagated(boolean b);

    /**
     * Provides the size of this bucket's content in bytes.
     *
     * @return the size of this bucket's content in bytes
     */
    int getContentSize();

    /**
     * Provides the content of this bucket.
     *
     * @return the content of this bucket
     */
    byte[] getContent();

    /**
     * Sets the content of this bucket.
     *
     * @param content the content for this bucket
     * @throws InvalidSizeException if content size is invalid 
     */
    void setContent(byte[] content) throws InvalidSizeException;

}